package com.cskaoyan.order.service.impl;

import com.cskaoyan.mall.commons.constant.SysRetCodeConstants;
import com.cskaoyan.mall.commons.exception.BizException;
import com.cskaoyan.mall.commons.result.AbstractResponse;
import com.cskaoyan.mall.order.constant.OrderRetCode;
import com.cskaoyan.mall.order.dto.PayOrderSuccessRequest;
import com.cskaoyan.mall.order.dto.PayOrderSuccessResponse;
import com.cskaoyan.order.biz.TransOutboundInvoker;
import com.cskaoyan.order.biz.context.AbsTransHandlerContext;
import com.cskaoyan.order.biz.context.TransHandlerContext;
import com.cskaoyan.order.biz.factory.OrderProcessPipelineFactory;
import com.cskaoyan.order.constant.OrderConstants;
import com.cskaoyan.order.dal.entitys.Order;
import com.cskaoyan.order.dal.entitys.OrderItem;
import com.cskaoyan.order.dal.entitys.Stock;
import com.cskaoyan.order.dal.persistence.OrderItemMapper;
import com.cskaoyan.order.dal.persistence.OrderMapper;
import com.cskaoyan.order.dal.persistence.OrderShippingMapper;
import com.cskaoyan.order.dal.persistence.StockMapper;
import com.cskaoyan.order.dto.*;
import com.cskaoyan.order.service.OrderCoreService;
import com.cskaoyan.order.utils.ExceptionProcessorUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

/**
 * 创建日期: 2022/04/22 16:30
 *
 * @author ChengWenqi
 */

@Slf4j
@Service
public class OrderCoreServiceImpl implements OrderCoreService {

    // 注入管道
    @Autowired
    OrderProcessPipelineFactory orderProcessPipelineFactory;

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    OrderItemMapper orderItemMapper;

    @Autowired
    StockMapper stockMapper;

    @Autowired
    OrderShippingMapper orderShippingMapper;


    @Override
    public CreateOrderResponse createOrder(CreateOrderRequest request) {
        log.info("OrderCoreServiceImpl.createOrder request :"+request);
        CreateOrderResponse response = new CreateOrderResponse();
        try {
            // 参数校验
            request.requestCheck();
            TransOutboundInvoker invoker = orderProcessPipelineFactory.build(request);
            // 启动流程
            invoker.start();
            // 获得加工后的context，并转换成 response
            AbsTransHandlerContext context = invoker.getContext();
            response = (CreateOrderResponse) context.getConvert().convertCtx2Respond(context);
            // 设置成功响应码和信息
            response.setCode(OrderRetCode.SUCCESS.getCode());
            response.setMsg(OrderRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("OrderCoreServiceImpl.createOrder occur Exception: " + e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
        }
        return response;
    }

    // 参考项目中只有未付款才能取消订单
    // todo：事务
    @Override
    public CancelOrderResponse cancelOrder(CancelOrderRequest request) {
        CancelOrderResponse response = new CancelOrderResponse();

        try {
            // 参数校验
            request.requestCheck();
            // 获取 orderId
            String orderId = request.getOrderId();
            // 根据 orderId，修改 订单状态-订单取消，更新时间，交易关闭时间
            Order order = new Order();
            order.setOrderId(orderId);
            order.setStatus(OrderConstants.ORDER_STATUS_TRANSACTION_CANCEL);
            order.setUpdateTime(new Date());
            order.setCloseTime(new Date());
            int update = orderMapper.updateByPrimaryKeySelective(order);
            if (update != 1) {
                log.error("订单更新失败！");
                throw new BizException(SysRetCodeConstants.DATA_NOT_EXIST.getCode(), SysRetCodeConstants.DATA_NOT_EXIST.getMessage());
            }

            // 根据 orderId，查询 order_item 表
            List<OrderItem> orderItemList = orderItemMapper.queryByOrderId(orderId);
            if (CollectionUtils.isEmpty(orderItemList)) {
                log.error("订单商品详情不存在！");
                throw new BizException(SysRetCodeConstants.DATA_NOT_EXIST.getCode(), SysRetCodeConstants.DATA_NOT_EXIST.getMessage());
            }
            for (OrderItem orderItem : orderItemList) {
                // 如果 order_item 的状态是 库存已锁定，改成 库存已释放，更新时间
                if (orderItem.getStatus() == 1) {
                    orderItem.setStatus(OrderConstants.ORDER_ITEM_STATUS_STOCK_FREE);
                    orderItem.setUpdateTime(new Date());
                    orderItemMapper.updateByPrimaryKeySelective(orderItem);

                    // 根据 itemId，到 stock 表中修改库存，冻结库存减少，可售卖库存增加
                    Long itemId = orderItem.getItemId();
                    Integer orderNum = orderItem.getNum();
                    Stock stock = stockMapper.selectStockForUpdate(itemId);
                    stock.setStockCount(orderNum.longValue());
                    stock.setLockCount(-orderNum);
                    stockMapper.updateStock(stock);
                }
            }
            // 设置成功响应码和信息
            response.setCode(OrderRetCode.SUCCESS.getCode());
            response.setMsg(OrderRetCode.SUCCESS.getMessage());
        } catch (BizException e) {
            log.error("OrderCoreServiceImpl.cancelOrder occur Exception: " + e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
        }
        return response;
    }

    // todo:事务
    @Override
    public DeleteOrderResponse deleteOrder(DeleteOrderRequest request) {
        DeleteOrderResponse response = new DeleteOrderResponse();

        try {
            // 参数校验
            request.requestCheck();
            // 获取orderId
            String orderId = request.getOrderId();
            // 根据orderId，删除 order 表对应记录
            orderMapper.deleteByPrimaryKey(orderId);

            // 根据orderId，删除 order_item 表对应记录
            Example example = new Example(OrderItem.class);
            example.createCriteria().andEqualTo("orderId", orderId);
            orderItemMapper.deleteByExample(example);

            // 根据orderId，删除 order_shipping 表对应记录
            orderShippingMapper.deleteByPrimaryKey(orderId);

            // 设置成功响应码和信息
            response.setCode(OrderRetCode.SUCCESS.getCode());
            response.setMsg(OrderRetCode.SUCCESS.getMessage());

        } catch (Exception e) {
            log.error("OrderCoreServiceImpl.deleteOrder occur Exception: " + e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
        }

        return response;
    }

    @Override
    public PayOrderSuccessResponse payOrderSuccess(PayOrderSuccessRequest request) {
        return null;
    }
}
